using System.Collections.Generic;
using System.IO;
using System;
using UnityEngine;

namespace SgsUI
{
    public static class LuaOutputer
    {
        public static void OutputLua(int width,int height,List<NodeData> nodeList,string name)
        {
            using (StreamWriter sw = new StreamWriter("Output/"+name+".lua"))
            {
                sw.WriteLine(@"local View = {width=" + width + ",height=" + height + ",children={");

                int indent = 0;

                for (int i = 0; i < nodeList.Count; i++)
                {
                    WriteNode(sw,indent + Define.indent,nodeList[i]);
                    if(i != nodeList.Count - 1)
                    {
                        sw.Write(",");
                    }
                    sw.Write("\n");
                }
                sw.WriteLine("}}");
            }
        }

        static void WriteNode(StreamWriter sw,int indent,NodeData nodeData)
        {
            string o_str = "";
            WriteSpace(sw,indent);
            sw.WriteLine("{");
            WriteSpace(sw,indent + Define.indent);
            for (int i = 0; i < nodeData.m_params.Count; i++)
            {
                ParamData cur_param = nodeData.m_params[i];
                o_str = WriteParamByType(sw,indent + Define.indent,o_str,cur_param);
            }

            sw.Write(o_str);

            sw.Write("\n");
            WriteSpace(sw,indent);
            sw.Write("}");
        }

        static string WriteParamByType(StreamWriter sw,int indent,string o_str,ParamData param)
        {
            if(param.value_type == DataType.String)
            {
                o_str = WriteParam(sw,indent,o_str,param.m_key + "=" + ValueString(param.m_string));
            }
            else if(param.value_type == DataType.Float)
            {
                o_str = WriteParam(sw,indent,o_str,param.m_key + "=" + param.m_float);
            }
            else if(param.value_type == DataType.Int)
            {
                o_str = WriteParam(sw,indent,o_str,param.m_key + "=" + param.m_int);
            }
            else if(param.value_type == DataType.NodeData)
            {
                sw.Write(o_str + "," + param.m_key + "={\n");
                o_str = "";

                for (int i = 0; i < param.m_list_data.Count; i++)
                {
                    WriteNode(sw,indent + Define.indent,param.m_list_data[i]);
                    if(i != param.m_list_data.Count - 1)
                    {
                        sw.Write(",");
                    }
                    sw.Write("\n");
                }

                WriteSpace(sw,indent);
                sw.Write("}");
            }
            else if(param.value_type == DataType.Align)
            {
                Align align = param.m_align;
                o_str = WriteParam(sw,indent,o_str,
                    param.m_key + "={" + ValueString(align.anchor) + "," + align.x + "," + align.y + "}"
                );
            }
            else if(param.value_type == DataType.Vector2)
            {
                o_str = WriteParam(sw,indent,o_str,
                    param.m_key + "={" + param.m_vec2.x + "," + param.m_vec2.y + "}"
                );
            }
            else if(param.value_type == DataType.Bool)
            {
                string boolValue = param.m_bool?"true":"false";
                o_str = WriteParam(sw,indent,o_str,
                    param.m_key + "=" + boolValue
                );
            }
            else if(param.value_type == DataType.ColorData)
            {
                ColorData color = param.m_color;
                if(color.a == 255)
                {
                    o_str = WriteParam(sw,indent,o_str,
                        param.m_key + "={" + color.r + "," + color.g + "," + color.b + "}"
                    );
                }
                else
                {
                    o_str = WriteParam(sw,indent,o_str,
                        param.m_key + "={" + color.r + "," + color.g + "," + color.b + "," + color.a +"}"
                    );
                }
                
            }

            return o_str;
        }

        static string WriteParam(StreamWriter sw,int indent,string o_str,string a_str)
        {
            if(o_str.Length > Define.maxLength)
            {
                sw.Write(o_str + ",\n");
                WriteSpace(sw,indent);
                o_str = a_str;
            }
            else
            {
                if(o_str != "")
                {
                    o_str += "," + a_str;
                }
                else
                {
                    o_str += a_str;
                }
            }

            return o_str;
        }

        static void WriteSpace(StreamWriter sw,int count)
        {
            for (int i = 0; i < count; i++)
            {
                sw.Write(" ");
            }
        }

        static string ValueString(string input)
        {
            string ret = "\"" + input + "\"";
            return ret;
        }
    }
}